#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <math.h>
#include <limits.h>

#define WIDTHOFFSET 18
#define PIXELOFFSET 1078
#define PI 3.14159265
#define ROW 2
#define COLUMN 3
int width, height, average;
unsigned char pixel[640][640];
unsigned int arr[262144];
void BubbleSort(unsigned int arr[], int totalELements);
void getData(FILE *);
void display();
int main(void) {
	char imagename[30];
	printf("\n Enter the image..");
	// fflush(stdout);
	gets(imagename);
	FILE *fp = fopen(imagename, "rb");
	if (fp == NULL)
		printf("Error..");
	int gDriver = DETECT;
	int gMode;
	int errorcode;
	struct palettetype pal;
	initgraph(&gDriver, &gMode, "C:\\TURBOC3\\BGI\\");
	errorcode = graphresult();
	if (errorcode != grOk)
		printf("\n%s", grapherrormsg(errorcode));
	getpalette(&pal);

	//Create Grayscale
	for (int i = 0; i < pal.size; i++) {
		setrgbpalette(pal.colors[i], i * 4, i * 4, i * 4);
	}
	getData(fp);
	display();
	getch();
	cleardevice();
	_fcloseall();
}

void getData(FILE *fp) {
	unsigned long img_width, img_height;
	fseek(fp, WIDTHOFFSET, SEEK_SET);
	fread(&img_width, 4, 1, fp);
	fread(&img_height, 4, 1, fp);
	fseek(fp, PIXELOFFSET, SEEK_SET);
	int sum = 0, index = 0;
	int rowSum = 0, colSum = 0, rowMean, colMean, rowColDiffSum = 0;
	width = (int) img_width;
	height = (int) img_height;
	unsigned char c;
	for (int i = 0; i < height; i++) {
		for (int j = 0; j < width; j++) {
			c = fgetc(fp);
			sum += (unsigned int) c;
			pixel[i][j] = c;
			arr[index++] = c;

		}
	}
	for (int i = 0; i < width; i++)
		rowSum += (int) pixel[ROW][i];
	rowMean = rowSum / width;
	for (int i = 0; i < height; i++)
		rowSum += (int) pixel[i][COLUMN];
	colMean = colSum / height;
	for (int i = 0; i < width; i++) {
		rowColDiffSum += (((int) pixel[ROW][i]) - rowMean)
				*(((int) pixel[i][COLUMN]) - colMean);
	}

	int cov = rowColDiffSum / width;
	int mean = sum / (height * width);
	//calculating variance
	unsigned int sumOfSquares = 0;
	for (int i = 0; i < index; i++) {
		sumOfSquares += (abs(arr[index] - mean) * abs(arr[index] - mean));
	}
	unsigned int variance = sumOfSquares / (index);
	unsigned int sd = sqrt(variance);
	BubbleSort(arr, index);
	//for median
	int median = 0;
	if ((index % 2) == 0) {
		median = (arr[(index / 2)] + arr[(int) ((index - 1) / 2)]) / 2;
	} else {
		median = arr[(index / 2)];
	}
	printf("The median is : %d\n", median);
	printf("The average is : %d\n", mean);
	printf("The variance is : %d\n", variance);
	printf("The standard deviation is : %d\n", sd);
	printf("The covariance is : %d\n", cov);
}

void display() {
	settextstyle(1, 0, 3);
	outtextxy(250, 35, "Bitmap Image");
	for (int row = 0; row < height; row++) {
		for (int col = 0; col < width; col++) {
			putpixel(col, 500 - row, pixel[row][col] / 16);

		}

	}

}
void BubbleSort(unsigned int arr[], int totalelements) {
	unsigned int temp;
	for (int i = 0; i < totalelements; i++) {
		for (int j = 0; j < (totalelements - 1); j++) {
			if (arr[j] > arr[j + 1]) {
				temp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
	}
}
